package com.tanglon.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tanglon.constants.AdminConstants;
import com.tanglon.constants.SystemConstants;
import com.tanglon.domain.ResponseResult;
import com.tanglon.domain.entity.Menu;
import com.tanglon.domain.entity.RoleMenu;
import com.tanglon.domain.vo.MenuTreeVo;
import com.tanglon.domain.vo.MenuVo;
import com.tanglon.domain.vo.RoleMenuTreeVo;
import com.tanglon.mapper.MenuMapper;
import com.tanglon.service.MenuService;
import com.tanglon.service.RoleMenuService;
import com.tanglon.utils.BeanCopyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;



/**
 * 菜单权限表(Menu)表服务实现类
 *
 * @author makejava
 * @since 2025-08-13 11:17:05
 */
@Service("menuService")
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {

    @Autowired
    private RoleMenuService roleMenuService;

    @Override
    public List<String> selectPermByUserId(Long id) {
        // TODO 如果是超级管理员，返回所有的权限
        if(id == 1L || id == 14787164048663L){
            LambdaQueryWrapper<Menu> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(Menu::getMenuType, AdminConstants.MENU,AdminConstants.BUTTON);
            wrapper.eq(Menu::getStatus, AdminConstants.STATUS_NORMAL);
            List<Menu> list = list(wrapper);
            List<String> collect = list.stream()
                    .map(Menu::getPerms)
                    .collect(Collectors.toList());
            return collect;
        }
        //不是则返回所具有的权限
        return getBaseMapper().selectPermsByUserId(id);
    }

    @Override
    public List<Menu> selectRouterMenuTreeByUserId(Long userId) {
        MenuMapper menuMapper = getBaseMapper();
        List<Menu> menus = null;
        // TODO 判断是否是管理员
        if(userId == 1L || userId == 14787164048663L){
            //如果是 获取所有符合要求的Menu
            menus = menuMapper.selectAllRouterMenu();
        }else{
            //否则  获取当前用户所具有的Menu
            menus = menuMapper.selectRouterMenuTreeByUserId(userId);
        }

        //构建tree
        //先找出第一层的菜单  然后去找他们的子菜单设置到children属性中
        List<Menu> menuTree = builderMenuTree(menus,0L);
        return menuTree;
    }

    /**
     * 获取菜单列表
     * @param menuName
     * @param status
     * @return
     */
    @Override
    public ResponseResult menuList(String menuName, String status) {
        LambdaQueryWrapper<Menu> queryWrapper = new LambdaQueryWrapper();
        //模糊查询
        queryWrapper.like(Objects.nonNull(menuName),Menu::getMenuName, menuName);
        queryWrapper.eq(Objects.nonNull(status),Menu::getStatus, status);
        queryWrapper.orderByAsc(Menu::getParentId,Menu::getOrderNum);
        List<Menu> menuList= list(queryWrapper);
        List<MenuVo> menuVoList = BeanCopyUtils.copyBeanList(menuList,MenuVo.class);
        return ResponseResult.okResult(menuVoList);
    }

    @Override
    public ResponseResult addMenu(Menu menu) {
        save(menu);
        return ResponseResult.okResult();
    }

    /**
     * 根据id查询菜单详情
     * @param id
     * @return
     */
    @Override
    public ResponseResult menuById(Long id) {
        Menu menu = getById(id);
        MenuVo menuVo = BeanCopyUtils.copyBean(menu,MenuVo.class);
        return ResponseResult.okResult(menuVo);
    }

    /**
     * 修改菜单
     * @param menu
     * @return
     */
    @Override
    public ResponseResult updateMenu(Menu menu) {
        //获取父菜单记录
        Menu parentMenu = getById(menu.getParentId());
        //获取父菜单的名字
        String parentMenuName = parentMenu.getMenuName();

        //当前修改菜单的菜单名
        String updateMenuName = menu.getMenuName();
        if(!updateMenuName.equals(parentMenu.getMenuName())){
            updateById(menu);
            return ResponseResult.okResult();
        }else {
            Integer code=500;
            String msg="修改菜单"+"\'"+updateMenuName+"\'"+"失败，上级菜单不能选择自己";
            return ResponseResult.okResult(code,msg);
        }
    }


    //    增加用户角色时，展示菜单的三级目录
    @Override
    public ResponseResult treeSelect() {
        //1. Menu表中的所有数据 转成MenuTreeVo集合        并设置(id,label，parentId)
        // Menu -> MenuTreeVo (id,label，parentId,children=null)
        List<MenuTreeVo> menuTreeVo = list().stream()
                .map(menu -> new MenuTreeVo(menu.getId(), menu.getMenuName(), menu.getParentId(), null))
                .collect(Collectors.toList());
        //2. 根据parent_id(参数2) 将列表menuTreeVo(参数1)建立成 3级菜单树      函数名builderMenuTree2
        List<MenuTreeVo> menuTreeVo1 = builderMenuTree2(menuTreeVo,0L);
        return ResponseResult.okResult(menuTreeVo1);
    }

    @Override
    public ResponseResult roleMenuTreeselect(Long id) {
        RoleMenuTreeVo roleMenuTreeVo = new RoleMenuTreeVo();
        //1.设置menus 把3级菜单展示出来
//        Menu -> MenuTreeVo集合
        List<MenuTreeVo> menuTreeVo = list().stream()
                .map(menu -> new MenuTreeVo(menu.getId(), menu.getMenuName(), menu.getParentId(), null))
                .collect(Collectors.toList());
        //根据parent_id(参数2) 将列表menuTreeVo(参数1)建立成 3级菜单树      函数名builderMenuTree2
        List<MenuTreeVo> menus = builderMenuTree2(menuTreeVo,0);

        roleMenuTreeVo.setMenus(menus);

        //2.设置checkedKeys（3级菜单中 用户id所具有的权限啊展示出来） 用户角色所关联的 菜单id
        LambdaQueryWrapper<RoleMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RoleMenu::getRoleId,id);
        List<RoleMenu> roleMenus = roleMenuService.list(queryWrapper);
        List<String> menuIds = roleMenus.stream()
                .map(roleMenu -> roleMenu.getMenuId().toString())
                .collect(Collectors.toList());
        roleMenuTreeVo.setCheckedKeys(menuIds);
        return ResponseResult.okResult(roleMenuTreeVo);
    }

    private List<MenuTreeVo> builderMenuTree2(List<MenuTreeVo> menuTreeVo, long parentId) {
        //第一层
        List<MenuTreeVo> collect = menuTreeVo.stream()
                .filter(m -> m.getParentId().equals(parentId)) //过滤出 父菜单
                //getChildren2(menuTreeVo, m1) 根据m1 在 menuTreeVo列表中 循环找子菜单(m1表示3个父菜单)
                .map(m1 -> m1.setChildren(getChildren2(menuTreeVo, m1)))  //第2,3层——循环设置children，
                .collect(Collectors.toList());
        return collect;
    }

    private List<MenuTreeVo> getChildren2(List<MenuTreeVo> menuTreeVo, MenuTreeVo m1) {
        //getChildren2(menuTreeVo, m1) 根据m1(m1表示3个父菜单) 在 menuTreeVo列表中 循环找子菜单
        List<MenuTreeVo> collect2 = menuTreeVo.stream()
                .filter(m2 -> m2.getParentId().equals(m1.getId())) //找1个父菜单的子菜单
                .map(m3 -> m3.setChildren(getChildren2(menuTreeVo, m3))) //第2,3层递归设置children，
                .collect(Collectors.toList());
        return collect2;
    }


    private List<Menu> builderMenuTree(List<Menu> menus, Long parentId) {
        List<Menu> menuTree = menus.stream()
                .filter(menu -> menu.getParentId().equals(parentId))
                .map(menu -> menu.setChildren(getChildren(menu, menus)))
                .collect(Collectors.toList());
        return menuTree;
    }
    /**
     * 获取存入参数的 子Menu集合
     * @param menu
     * @param menus
     * @return
     */
    private List<Menu> getChildren(Menu menu, List<Menu> menus) {
        List<Menu> childrenList = menus.stream()
                .filter(m -> m.getParentId().equals(menu.getId()))
                .map(m->m.setChildren(getChildren(m,menus)))
                .collect(Collectors.toList());
        return childrenList;
    }
}

